use lazy_static::lazy_static;
use regex::Regex;
use std::error::Error;
use std::fmt;
use std::fs;
use std::str::FromStr;

fn parse_data() -> Vec<(usize, usize, String, String)> {
    let contents = fs::read_to_string("input.txt").unwrap();

    lazy_static! {
        static ref RE: Regex = Regex::new(r"(\d+)\-(\d+) ([a-z]): ([a-zA-Z]+)").unwrap();
    }
    let mut parsed = Vec::new();
    for cap in RE.captures_iter(&contents) {
        let (cap1, cap2, cap3, cap4) = (&cap[1], &cap[2], &cap[3], &cap[4]);
        parsed.push((
            cap1.parse::<usize>().unwrap(),
            cap2.parse::<usize>().unwrap(),
            cap3.to_string(),
            cap4.to_string(),
        ));
    }
    return parsed;
}

fn part1() {
    let parsed = parse_data();
    println!("Part1:");
    //println!("parsed: {:?}", &parsed);

    let mut valid_count = 0;
    for (low, high, c, s) in &parsed {
        let matches = s.matches(c).count();
        if matches >= *low && matches <= *high {
            valid_count += 1;
        }
    }

    println!("Valid count: {}", valid_count);
}

fn part2() {
    let parsed = parse_data();
    println!("Part2:");
    //println!("parsed: {:?}", &parsed);

    let mut valid_count = 0;
    for (low, high, c, s) in &parsed {
        let (low, high) = (*low - 1, *high - 1);
        let mut matches = 0;
        if low < s.len() && &s[low..low + 1] == c {
            matches += 1;
        }
        if high < s.len() && &s[high..high + 1] == c {
            matches += 1;
        }
        if matches == 1 {
            valid_count += 1;
        }
    }

    println!("Valid count: {}", valid_count);
}

fn main() {
    part1();
    part2();
}
